home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dirut
/
dosdir21.zip
/
DOSDIR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-22
|
10KB
|
358 lines
/*
dosdir.c:
DOSDIR V2.1: A Portable DOS/UNIX/VMS Directory Interface
Implementation of the DOS directory functions (findfirst and findnext)
on MS-DOS, UNIX and VMS platforms using the appropriate file & directory
structure.
Provides the DOS directory framework for MS-DOS/UNIX/VMS application
portability.
Supports MS-DOS with Borland C++, Turbo C, or Microsoft C V6.0/7.0,
Sun with GNU C compiler, DEC Alpha (OSF-1), VAX/VMS C,
and other comparable platforms.
Jason Mathews
NASA/Goddard Space Flight Center
Code 633.2
Greenbelt, Maryland 20771-0001 USA
e-mail: mathews@nssdca.gsfc.nasa.gov
Copyright (C) 1994 Jason Mathews.
Permission is granted to any individual or institution to use, copy,
redistribute or modify this software so long as it is not sold for
profit, provided this copyright notice is retained.
Modification history:
V1.0 02-May-91, Original version.
V2.0 13-May-94, Reimplemented findfirst/findnext with ffblk structure
to match MS-DOS externally, fixed wildcard evaluation
function.
V2.1 08-Jun-94, Replaced wildcard evaluation function with recursive
function provided by Info-ZIP's portable UnZip,
added dd_ prefix to most functions & constants,
added VMS functions + MSC/TURBOC macros.
*/
#include <string.h>
#include "dosdir.h"
struct stat dd_sstat; /* global stat structure of last successful file
* returned by findfirst/findnext functions available
* to query for more detailed information.
*/
#ifdef MSDOS
# ifdef __TURBOC__
# define FSTRUCT struct ffblk
# define FATTR FA_HIDDEN+FA_SYSTEM+FA_DIREC
# define FFIRST(n,d,a) findfirst(n,d,a)
# define FNEXT(d) findnext(d)
# define FNAME ff_name
# define FATTRIB ff_attrib
# define FSIZE ff_fsize
# define FDATE ff_fdate
# define FTIME ff_ftime
# else /* !__TURBOC__ */
# define FSTRUCT struct find_t
# define FATTR _A_HIDDEN+_A_SYSTEM+_A_SUBDIR
# define FFIRST(n,d,a) _dos_findfirst(n,a,d)
# define FNEXT(d) _dos_findnext(d)
# define FNAME name
# define FATTRIB attrib
# define FSIZE size
# define FDATE wr_date
# define FTIME wr_time
# endif /* ?__TURBOC__ */
#else /* ?UNIX/VMS */
# include "match.h"
/* stub functions for get/set disk
* fake MS-DOS functions that do not apply to unix or vms:
*/
int getdisk()
{
return 0;
}
int setdisk( drive )
int drive;
{
return 0;
}
#endif /* ?MSDOS */
#if defined (MSDOS)
# ifndef __TURBOC__
/*
* getdisk
*
* Returns: -1 if error, otherwise: 0=drive A, 1=drive B, and so on.
*/
int getdisk()
{
unsigned d;
_dos_getdrive(&d);
return ((int)d - 1);
}
/*
* setdisk: 0=drive A, 1=drive B, and so on.
*
* Returns: total number of drive available
*
*/
int setdisk( int drive )
{
unsigned numdrives;
_dos_setdrive((unsigned) (drive + 1), &numdrives);
return numdrives;
}
# endif /* ?!__TURBOC__ */
# if 0
/* function used if we want to fake stat info instead of failing the file,
* but I cannot find a case where stat fails after findfirst/findnext succeeds.
*/
/* fill stat structure given the DOS findfirst structure */
static void dd_fillstatbuf( FSTRUCT* fb )
{
struct date fdate;
struct time ftime;
/*
* convert struct ffblk date/time format -> dos format
*/
fdate.da_year = (fb->FDATE>>9) + 1980;
fdate.da_day = fb->FDATE & 0x1f;
fdate.da_mon = fb->FDATE>>5 & 0xf;
ftime.ti_hour = fb->FTIME>>11;
ftime.ti_min = fb->FTIME>>5 & 0x3f;
ftime.ti_sec = 2*(fb->FTIME & 0x1f);
ftime.ti_hund = 0;
/* convert dos time to t_time format */
dd_sstat->st_atime =
dd_sstat->st_mtime =
dd_sstat->st_ctime = dostounix (&fdate, &ftime);
/*
* set file mode flags
*/
dd_sstat->st_mode = S_IREAD;
if (fb->ff_attrib & DD_DIREC) dd_sstat->st_mode |= (S_IFDIR | S_IEXEC);
else if (fb->ff_attrib & DD_DEVICE) /* non-documented findfirst attribute */
dd_sstat->st_mode |= S_IFCHR;
else dd_sstat->st_mode |= S_IFREG;
if (!(fb->ff_attrib & DD_RDONLY)) dd_sstat->st_mode |= S_IWRITE;
/* other msdos stat fields not used by dosdir */
dd_sstat->st_uid = dd_sstat->st_gid = 0;
dd_sstat->st_size = fb->FSIZE;
dd_sstat->st_nlink = 1;
dd_sstat->st_ino = 0;
dd_sstat->st_rdev = dd_sstat->st_dev = fb->ff_attrib & DD_DEVICE ? -1 : 3;
}
# endif
static int dd_initstruct( dd_ffblk* fb )
{
fb->dd_name = fb->dos_fb.FNAME;
/* ".." entry refers to the directory entry of the cwd and *NOT* the
* parent directory, so we use "." instead.
*/
if (stat(!strcmp(fb->dd_name, "..") ? "." : fb->dd_name, &dd_sstat))
return -1; /* stat failed! */
fb->dd_time = dd_sstat.st_mtime;
fb->dd_size = fb->dos_fb.FSIZE;
fb->dd_mode = fb->dos_fb.FATTRIB & DD_DOSATTRIBS |
dd_sstat.st_mode & ~DD_DOSATTRIBS;
return 0;
}
/*
* Function: dd_findnext
*
* Purpose: Use dd_findnext after dd_findfirst to find the remaining files
*
* Returns: zero if successful, otherwise, it returns a -1
* and sets errno either to the constant ENOENT indicating
* that the file could not be found, or to ENMFILE
* signifying that there are no more files.
*
* Parms:
* dd_ffblk* fb = structure to hold results of search
*/
int dd_findnext( dd_ffblk* fb )
{
int rc;
/* repeat until file info is initialized or no more files are left */
while ((rc=FNEXT(&fb->dos_fb)) == 0 && (rc=dd_initstruct(fb)) != 0);
return rc;
}
/*
* Function: dd_findfirst
*
* Purpose: Find file matching specification in specified directory
* given directory information
*
* Returns: zero if successful, otherwise, it returns a -1
* and sets errno either to the constant ENOENT indicating
* that the file could not be found, or to ENMFILE
* signifying that there are no more files.
*
* Parms:
* char *filespec = filename to search for including path
* dd_ ffblk* fb = structure to hold results of search
* int attrib = file attributes to match
*/
int dd_findfirst( const char *path, dd_ffblk *fb, int attrib )
{
int rc;
if ((rc = FFIRST( path, &fb->dos_fb, attrib & DD_DOSATTRIBS)) == 0)
{
if ((rc = dd_initstruct(fb)) != 0) /* initialization failed? */
rc = dd_findnext( fb );
}
return rc;
}
#elif defined (VMS)
int dd_findnext( dd_ffblk* fb )
{
int rc;
while ((rc = SYS$SEARCH(&fb->fab, 0, 0)) == RMS$_NORMAL)
{
char *s;
fb->rsa[fb->nam.nam$b_rsl] = '\0'; /* terminate filename */
if (stat(fb->rsa, &dd_sstat)) /* if stat fails then we have no */
continue; /* priviledge to read file, so skip it */
if (dd_sstat.st_mode & S_IFDIR && !(fb->dd_attribs & DD_DIREC))
continue;
s = strchr(fb->rsa, DIR_END);
fb->dd_name = s ? s + 1 : fb->rsa;
if (dd_match(fb->dd_name, fb->filespec, 1))
{
fb->dd_size = dd_sstat.st_size;
fb->dd_time = dd_sstat.st_mtime;
fb->dd_mode = dd_sstat.st_mode;
return 0; /* OK: match found */
}
} /* while */
memset(fb, 0x0, sizeof(dd_ffblk)); /* Invalidate structure */
errno = ENOENT; /* No file found */
return -1; /* Search failed */
}
int dd_findfirst( const char *path, dd_ffblk *fb, int attrib )
{
char *s;
strcpy(fb->path, path);
s = strchr(fb->path, DIR_END);
if (!s)
s = strrchr(fb->path, ':'); /* check device/node */
if (s)
{
strncpy(fb->rms_filespec, fb->path, s - fb->path + 1);
strcat(fb->rms_filespec, "*.*");
fb->filespec = s + 1;
printf("filespec = %s\n", fb->rms_filespec);
}
else
{
strcpy(fb->rms_filespec, "*.*");
fb->filespec = fb->path;
}
/* if no version number specified then add one */
s = strchr(fb->path, ';');
if (!s) strcat(fb->path, ";*");
fb->fab = cc$rms_fab;
fb->nam = cc$rms_nam;
fb->fab.fab$l_dna = &fb->rms_filespec;
fb->fab.fab$b_dns = strlen(fb->rms_filespec);
fb->fab.fab$l_nam = &fb->nam;
fb->nam.